﻿using UnityEngine;

class MonsterControl : MonoBehaviour
{

    private GameObject player;
    //初始位置
    private Vector3 initPosition;
    private Animator animator;
    private AnimatorStateInfo animatorState;

    //游走半径，移动状态下，如果超出游走半径会返回出生位置，小于追击半径
    public float wanderRadius = 10;
    //警戒半径,怪物会停下，并且面朝你
    public float alertRadius = 15;
    //自卫半径，怪物会追击玩家，小于警戒半径
    public float defendRadius = 10;
    //追击半径
    public float chaseRadius = 20;

    //攻击距离，小于自卫半径
    public float attackRange = 5;
    //移动速度
    public float walkSpeed = 1;
    //跑动速度
    public float runSpeed = 5;
    //转身速度
    public float turnSpeed = 0.1f;

    public MonsterState showCurType;

    public  enum MonsterState
    {
        STAND,//站在原地
        CHECK,//原地观察
        WALK,//移动
        WARN,//盯着玩家
        CHASE,//追击玩家
        RETURN,//返回出生点
        ATTACK,//攻击玩家
        DIE//死亡状态
    }

    private MonsterState currentState = MonsterState.STAND;

    public float[] actionWeight = { 3000, 3000, 4000 };//待机时动作权重，呼吸，观察，移动
    public float actRestTime = 5;
    private float lastActTime;

    private float distanceToPlayer;
    private float distanceToInitPos;
    private Quaternion targetRotation;

    private bool isWarned = false;//警告
    private bool isRunning = false;

    private void Start()
    {
        player = GameObject.FindGameObjectWithTag("Player");
        animator = GetComponent<Animator>();

        initPosition = transform.position;
        //检查设置
        defendRadius = Mathf.Min(alertRadius, defendRadius);
        attackRange = Mathf.Min(defendRadius, attackRange);
        wanderRadius = Mathf.Min(chaseRadius, wanderRadius);

        RandomAction();
    }

    void RandomAction()
    {
        lastActTime = Time.time;
        float number = Random.Range(0, actionWeight[0] + actionWeight[1] + actionWeight[2]);
        if(number <= actionWeight[0])
        {
            currentState = MonsterState.STAND;
        }else if(actionWeight[0] < number && number <= actionWeight[0] + actionWeight[1])
        {
            currentState = MonsterState.CHECK;
        }else if(actionWeight[0] + actionWeight[1] < number && number <= actionWeight[0] + actionWeight[1] + actionWeight[2])
        {
            currentState = MonsterState.WALK;
            targetRotation = Quaternion.Euler(0, Random.Range(1, 5) * 90, 0);
        }
    }
    private void Update()
    {
        showCurType = currentState;
        switch (currentState)
        {
            case MonsterState.STAND:
                if(Time.time - lastActTime > actRestTime)
                {
                    RandomAction();//随机切换指令
                }
                EnemyDistanceCheck();
                SetAnimator(EnumAnimatorType.stand);
                break;
            case MonsterState.CHECK:
                ///待机状态，由于观察动画时间较长，并希望动画完整播放，故等待时间是根据一个完整动画的播放长度，而不是指令间隔时间
                if (Time.time - lastActTime > animator.GetCurrentAnimatorStateInfo(0).length)
                {
                    RandomAction();
                }
                EnemyDistanceCheck();
                SetAnimator(EnumAnimatorType.stand);
                break;
            case MonsterState.WALK://游走状态
                transform.Translate(Vector3.forward * Time.deltaTime * walkSpeed);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, turnSpeed);
                if(Time.time - lastActTime > actRestTime)
                {
                    RandomAction();
                }
                WanderRadiusCheck();
                SetAnimator(EnumAnimatorType.run);
                break;
            case MonsterState.WARN://警戒状态
                if(!isWarned)
                {
                    isWarned = true;
                }
                //持续朝向玩家位置
                targetRotation = Quaternion.LookRotation(player.transform.position - transform.position, Vector3.up);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, turnSpeed);
                //该状态下的检测指令
                WarningCheck();
                SetAnimator(EnumAnimatorType.stand);
                break;
            case MonsterState.CHASE://追击状态
                if(!isRunning)
                {
                    //animator.SetTrigger("Run");
                    isRunning = true;
                }
                transform.Translate(Vector3.forward * Time.deltaTime * runSpeed);
                //朝向玩家位置
                targetRotation = Quaternion.LookRotation(player.transform.position - transform.position, Vector3.up);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, turnSpeed);

                ChaseRadiusCheck();
                SetAnimator(EnumAnimatorType.run);
                break;
            case MonsterState.ATTACK://攻击状态
                if(ChaseRadiusCheck())
                    Mgr.fightMgr.MonsterAttackPlayer(GetComponent<Monster>().MonsterId);
                break;
            case MonsterState.RETURN://返回状态
                //朝向初始位置移动
                targetRotation = Quaternion.LookRotation(initPosition - transform.position, Vector3.up);
                transform.rotation = Quaternion.Slerp(transform.rotation, targetRotation, turnSpeed);
                transform.Translate(Vector3.forward * Time.deltaTime * runSpeed);
                ReturnCheck();
                SetAnimator(EnumAnimatorType.run);
                break;
            case MonsterState.DIE:
                SetAnimator(EnumAnimatorType.die);
                break;
               
        }
    }

    //原地状态的检测
    void EnemyDistanceCheck()
    {
        distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
        if(distanceToPlayer < attackRange)
        {//攻击
            currentState = MonsterState.ATTACK;
        }
        else if(distanceToPlayer < defendRadius)
        {//追击
            currentState = MonsterState.CHASE;
        }else if(distanceToPlayer < alertRadius)
        {//警戒
            currentState = MonsterState.WARN;
        }
    }

    //警告状态的检测
    void WarningCheck()
    {
        distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);

        if(distanceToPlayer < defendRadius)
        {
            isWarned = false;
            currentState = MonsterState.CHASE;
        }
        if (distanceToPlayer > alertRadius)
        {
            isWarned = false;
            RandomAction();
        }
    }

    //游走状态的检测
    void WanderRadiusCheck()
    {
        distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
        distanceToInitPos = Vector3.Distance(transform.position, initPosition);

        if(distanceToPlayer < attackRange)
        {//攻击
            currentState = MonsterState.ATTACK;
        }
        else if(distanceToPlayer < defendRadius)
        {
            currentState = MonsterState.CHASE;
        }else if(distanceToPlayer < alertRadius)
        {
            currentState = MonsterState.WARN;
        }
        if(distanceToInitPos > wanderRadius)
        {
            //调整朝向
            targetRotation = Quaternion.LookRotation(initPosition - transform.position, Vector3.up);
        }
    }

    //追击状态检测
    bool ChaseRadiusCheck()
    {
        distanceToPlayer = Vector3.Distance(player.transform.position, transform.position);
        distanceToInitPos = Vector3.Distance(player.transform.position, initPosition);

        if (GetComponent<Monster>().info.Health <= 0)
        {
            currentState = MonsterState.DIE;
            return false ;
        }

        if(distanceToPlayer < attackRange)
        {//攻击
            currentState = MonsterState.ATTACK;
        }
        else
        {
            currentState = MonsterState.CHASE;
        }
        if (distanceToInitPos > chaseRadius || distanceToPlayer > alertRadius)
        {
            currentState = MonsterState.RETURN;
        }
        return currentState == MonsterState.ATTACK;
    }

    //超出追击半径，返回状态的检测，不再检测距离
    void ReturnCheck()
    {
        distanceToInitPos = Vector3.Distance(transform.position, initPosition);
        //如果已经接近初始位置，则随机一个状态
        if(distanceToInitPos < 0.5f)
        {
            isRunning = false;
            RandomAction();
        }
    }

    //设置动作
    public void SetAnimator(EnumAnimatorType type)
    {
        animatorState = animator.GetCurrentAnimatorStateInfo(0);

        if (type == EnumAnimatorType.run)
        {
            if (!animatorState.IsName("Run"))
                animator.SetBool("Run", true);
        }else if(type == EnumAnimatorType.stand)
        {
            animator.SetBool("Run", false);
        }else if(type == EnumAnimatorType.attack)
        {
            animator.SetTrigger("Attack");
        }else if(type == EnumAnimatorType.die)
        {
            animator.SetTrigger("Die");
        }
    }
}
public enum EnumAnimatorType
{
    run,
    stand,
    attack,
    die
}
